#ifndef __core_h__
#define __core_h__

#include "define.h"
#include "style.h"
#include "layout.h"
#include "paint.h"
#include "functor.h"

#include "../xml/xml.h"
#include "../tool/base.h"
#include "../win/winfactory.h"

#include <map>
#include <string>
#include <vector>


namespace core
{



/*
 * @breif: property name.
 */
extern const char * COMMON_CONTROL_PROPERTY_ID;
extern const char * COMMON_CONTROL_PROPERTY_VISIBLE;
extern const char * COMMON_CONTROL_PROPERTY_TITLE;
extern const char * COMMON_CONTROL_PROPERTY_TABSTOP;
extern const char * COMMON_CONTROL_PROPERTY_ZINDEX;
extern const char * COMMON_CONTROL_PROPERTY_ALPHA;
extern const char * COMMON_CONTROL_PROPERTY_DRAG;





/*
 * @breif: face window base.
 */
class FaceWindow 
    : public FaceObject
{
public:
    FaceWindow();

public:
    std::string         id_;
    std::string         class_name_;
    bool                visible_;
    std::wstring        tip_;
    bool                tab_stop_;
    int                 z_index_;
    int                 alpha_;
    bool                drag_;
    FaceStyle           style_;

public:
    virtual FaceObjectTrait Trait()    { return FACE_OBJECT_TRAIT_CONTROL; }
    virtual WindowState     State()    { return window_state_;          }
    virtual bool            IsNewLine(){ return false;                  }

    uint                DispatchMessage( uint msg, uint w_param, uint l_param );
    void                AddMessageObserver( IMessageObserver *observer );
    void                RemoveMessageObserver( IMessageObserver *observer );
    void                SetMessageFilter( IMessageFilter *filter );

    virtual FaceWindow* HitTest( int x, int y );

    void                Destroy();

    virtual std::wstring    Value();
    std::wstring            GetInnerText();

    void                UpdateRect( rect update );
    bool                UpdateLayout( int x, int y, rect &update );
    bool                UpdateLayout( rect &update );
    virtual void        Offset( int x, int y );
    void                Deflate( int left, int top, int right, int bottom );
    void                Inflate( int left, int top, int right, int bottom );

public:
    const std::string&  GetName()                                   { return name_; }
    void                SetName( const std::string &name )          { name_ = name; }

    void                SetHandleDelegate( HandleDelegate *delegate );

    rect                GetBoundaryRect()                           { return boundary_rect_; }
    rect                GetBorderRect()                             { return border_rect_;     }
    rect                GetContentRect()                            { return content_rect_;  }

public:
    operator std::string(){ return id_; }

public:
    void                InsertBeginChild( FaceWindow *add );
    void                InsertEndChild( FaceWindow *add );
    void                InsertBeforeChild( FaceWindow *add, FaceWindow *before );
    void                InsertAfterChild( FaceWindow *add, FaceWindow *after );
    void                ReplaceChild( FaceWindow *with, FaceWindow *replace );
    void                RemoveChild( FaceWindow *remove );

    FaceWindow*         FirstChild()                        { return first_;     }
    FaceWindow*         LastChild()                         { return last_;      }
    FaceWindow*         FindChild( const std::string &id );
    FaceWindow*         FindChild( const std::string &id, bool deep );

    FaceWindow*         Parent()                            { return parent_;    }
    FaceWindow*         PreviousSibling()                   { return prev_;      }
    FaceWindow*         NextSibling()                       { return next_;      }

protected:
    std::string         name_;
    WindowState         window_state_;

    HandleDelegate     *handle_delegate_;

    dword               state_;
    rect                boundary_rect_;
    rect                border_rect_;
    rect                content_rect_;
    layout              parent_layout_;

protected:
    FaceWindow         *parent_;

    FaceWindow         *first_;
    FaceWindow         *last_;
    FaceWindow         *prev_;
    FaceWindow         *next_;

protected:
    typedef std::vector<IMessageObserver*>      _observers;
    _observers          observer_;

    IMessageFilter     *message_filter_;

protected:
    bool ParseAttribute( const XmlElement *element, const FaceStyleManager *manager );
    bool ParseChildren( const XmlElement *element, const FaceStyleManager *manager );

    bool AnalyseStyle( const char *value, const char *classname, const FaceStyleManager *manager );
    void ChangeWindowState( WindowState state );
    void ChangeActionState( dword add, dword remove );

    void NotifyObservers( uint msg, uint w_param, uint l_param, bool before );

public:
    DECLARE_ATTRIBUTE_MAP()

protected:
    BEGIN_MESSAGE_MAP()
        MESSAGE_HANDLE( FM_LOAD,            OnLoad        )
        MESSAGE_HANDLE( FM_LAYOUT,          OnLayout      )
        MESSAGE_HANDLE( FM_ADJUST,          OnAdjust      )
        MESSAGE_HANDLE( FM_PAINT,           OnPaint       )
        MESSAGE_HANDLE( FM_MOUSEHOVER,      OnMouseHover  )
        MESSAGE_HANDLE( FM_MOUSELEAVE,      OnMouseLeave  )
        MESSAGE_HANDLE( FM_LBUTTONDOWN,     OnLButtonDown )
        MESSAGE_HANDLE( FM_LBUTTONUP,       OnLButtonUp   )
        MESSAGE_HANDLE( FM_MOUSEWHEEL,      OnMouseWheel  )
        MESSAGE_HANDLE( FM_RBUTTONDOWN,     OnRButtonDown )
        MESSAGE_HANDLE( FM_RBUTTONUP,       OnRButtonUp   )
        MESSAGE_HANDLE( FM_KEYDOWN,         OnKeyDown     )
        MESSAGE_HANDLE( FM_KEYUP,           OnKeyUp       )
        MESSAGE_HANDLE( FM_CHAR,            OnChar        )
    END_MESSAGE_MAP()

    uint OnLoad         ( uint, uint );
    uint OnLayout       ( uint, uint );
    uint OnAdjust       ( uint, uint );
    uint OnPaint        ( uint, uint );
    uint OnMouseHover   ( uint, uint );
    uint OnMouseLeave   ( uint, uint );
    uint OnLButtonDown  ( uint, uint );
    uint OnLButtonUp    ( uint, uint ); 
    uint OnMouseWheel   ( uint, uint ){ return true; }
    uint OnRButtonDown  ( uint, uint ){ return true; }
    uint OnRButtonUp    ( uint, uint ){ return true; }
    uint OnKeyDown      ( uint, uint ){ return true; }
    uint OnKeyUp        ( uint, uint ){ return true; }
    uint OnChar         ( uint, uint ){ return true; }

protected:
    int BeginPaint( FacePainter *painter, rect *clip );
    void EndPaint( FacePainter *painter, int clip );
    void Draw( FacePainter *painter );
    void DrawChild( FacePainter *painter, rect *clip );

private:
    DISABLE_COPY_AND_ASSIGN(FaceWindow)
};





/*
 * @breif: special text node.
 */
class FaceText : public FaceWindow
{
public:
    FaceText()
    {
    }

    std::wstring Value(){ return value_; }
    void         Offset( int x, int y );

private:
    std::wstring value_;

    struct token
    {
        core::rect rect;
        int        begin;
        int        end;

        token() : begin(0), end(0){}
    };

    typedef std::vector<token> _tokens;
    _tokens tokens_;

public:
    DECLARE_ATTRIBUTE_MAP()

protected:
    BEGIN_MESSAGE_MAP()
        MESSAGE_HANDLE( FM_LAYOUT, OnLayout )
        MESSAGE_HANDLE( FM_PAINT,  OnPaint  )
    END_MESSAGE_MAP()

    uint OnLayout( uint, uint );
    uint OnPaint ( uint, uint );

private:
    DISABLE_COPY_AND_ASSIGN(FaceText)
};



};
#endif